package player;

import jaco.mp3.player.MP3Player;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Observable;

import player.state.IdleState;
import player.state.PauseState;
import player.state.PlayerState;
import player.state.PlayingState;

/**
 * Player class, used to play an MPEG audio file. Has many states.
 * @author Pawin Suthipornopas 5510546123
 */
public class MusicPlayer extends Observable {
	
	private MP3Player player;
	private PlayerState state;
	public final PlayerState IDLE_STATE;
	public final PlayerState PLAYING_STATE;
	public final PlayerState PAUSE_STATE;
	
	private int trackID = 1;
	private int currentID = 1;
	
	private Map<Integer, File> map = new HashMap<Integer, File>();

	/**
	 * Create new player with default value and idle state.
	 */
	public MusicPlayer() {
		player = new MP3Player();
		
		IDLE_STATE = new IdleState(player, this);
		PLAYING_STATE = new PlayingState(player, this);
		PAUSE_STATE = new PauseState(player, this);
		
		state = IDLE_STATE;
		
		//TODO: Implemented the shuffle feature.
		//List<Integer> list = new ArrayList<Integer>(map.keySet());
		//Collections.shuffle(list);
	}

	
	/**
	 * Insert tracks to the playlist.
	 * @param files is the path of multiple files.
	 */
	public void add(File[] files){
		for( File file : files ){
			if ( file == null )
				continue;
			player.addToPlayList(file);
			setChanged();
			notifyObservers(file);
			map.put(trackID++, file);
		}
	}

	/**
	 * Stop the player. Using the current state.
	 */
	public void handleStop() {
		state.handleStop();
	}

	/**
	 * Start the player. Using the current state.
	 */
	public void handlePlay() {
		setChanged();
		notifyObservers();
		state.handlePlay();
	}
	
	/**
	 * Pause the player. Using the current state.
	 */
	public void handlePause(){
		state.handlePause();
	}
	
	/**
	 * Skip to the next song. Using the current state.
	 */
	public void handleNext() {
		currentID++;
		setChanged();
		notifyObservers();
		state.handleNext();
	}
	
	/**
	 * Skip to the previous song. Using the current state.
	 */
	public void handlePrevious() {
		currentID--;
		setChanged();
		notifyObservers();
		state.handlePrevious();
	}
	
	/**
	 * Set repeating of the playlist, on or off.
	 */
	public void setRepeat(boolean repeat){
		player.setRepeat(repeat);
	}
	
	/**
	 * Set shuffling of the playlist, on or off.
	 */
	public void setShuffle(boolean shuffle){
		player.setShuffle(shuffle);
	}

	/**
	 * Set the state of the player.
	 * @param state
	 *            is the state to be set.
	 */
	public void setState(PlayerState state) {
		this.state = state;
	}
	
	/**
	 * Get the current track name of this player as a string.
	 * @return string represented that track.
	 */
	public String getTrack(){
		if (currentID == trackID && player.isRepeat()){
			currentID = 1;
		}
		else if (currentID == trackID)
			currentID--;
		else if (currentID == 0)
			currentID++;
		return map.get(currentID).getName().toString();
	}
	
	/**
	 * Get the latest track ID of this player.
	 * @return integer represented track number.
	 */
	public int getTrackID(){
		return trackID;
	}
	
	/**
	 * Get the current track ID of this player.
	 * @return integer represented current track number.
	 */
	public int getCurrentID(){
		return currentID;
	}
}